;(function(){

	window.requestAnimationFrame	=	window.requestAnimationFrame
									||	window.webkitRequestAnimationFrame
									||	window.mozRequestAnimationFrame;

	window.cancelAnimationFrame		=	window.cancelAnimationFrame
									||	window.webkitCancelAnimationFrame
									|| 	window.mozCancelAnimationFrame
									|| 	window.cancelRequestAnimationFrame
									|| 	window.webkitCancelRequestAnimationFrame
									||	window.mozCancelRequestAnimationFrame;

	//当浏览器不支持 requestAnimationFrame 或者 cancelAnimationFrame 时，使用setTimeout/clearTimeout做兼容处理
	;(function(){
		if(!requestAnimationFrame){
			var lastTime = Date.now();
			window.requestAnimationFrame = function(callback){
				var nowTime = Date.now();
				var delay = Math.max(16.7 - (nowTime - lastTime),0);
				var id = setTimeout(callback,delay);
				lastTime = nowTime + delay;

				return id;

			}
		}


		if(!cancelAnimationFrame){
			window.cancelAnimationFrame = function(id){
				clearTimeout(id);
			}
		}

	})();




})();


function tap(el,fn){
	var startPoint = {};
	el.addEventListener('touchstart', function(e) {
		startPoint = {
			x: e.changedTouches[0].pageX,
			y: e.changedTouches[0].pageY
		}
	});
	el.addEventListener('touchend', function(e) {
		var nowPoint = {
			x: e.changedTouches[0].pageX,
			y: e.changedTouches[0].pageY
		}
		if(Math.abs(nowPoint.x - startPoint.x) < 5 && Math.abs(nowPoint.y - startPoint.y) < 5){
			fn && fn.call(el,e);
		}
	});
}

var Tween = {
	linear: function (t, b, c, d){
		return c*t/d + b;
	},
	easeIn: function(t, b, c, d){
		return c*(t/=d)*t + b;
	},
	easeOut: function(t, b, c, d){
		return -c *(t/=d)*(t-2) + b;
	},
	easeBoth: function(t, b, c, d){
		if ((t/=d/2) < 1) {
			return c/2*t*t + b;
		}
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInStrong: function(t, b, c, d){
		return c*(t/=d)*t*t*t + b;
	},
	easeOutStrong: function(t, b, c, d){
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeBothStrong: function(t, b, c, d){
		if ((t/=d/2) < 1) {
			return c/2*t*t*t*t + b;
		}
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	elasticIn: function(t, b, c, d, a, p){
		if (t === 0) { 
			return b; 
		}
		if ( (t /= d) == 1 ) {
			return b+c; 
		}
		if (!p) {
			p=d*0.3; 
		}
		if (!a || a < Math.abs(c)) {
			a = c; 
			var s = p/4;
		} else {
			var s = p/(2*Math.PI) * Math.asin (c/a);
		}
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	elasticOut: function(t, b, c, d, a, p){
		if (t === 0) {
			return b;
		}
		if ( (t /= d) == 1 ) {
			return b+c;
		}
		if (!p) {
			p=d*0.3;
		}
		if (!a || a < Math.abs(c)) {
			a = c;
			var s = p / 4;
		} else {
			var s = p/(2*Math.PI) * Math.asin (c/a);
		}
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},    
	elasticBoth: function(t, b, c, d, a, p){
		if (t === 0) {
			return b;
		}
		if ( (t /= d/2) == 2 ) {
			return b+c;
		}
		if (!p) {
			p = d*(0.3*1.5);
		}
		if ( !a || a < Math.abs(c) ) {
			a = c; 
			var s = p/4;
		}
		else {
			var s = p/(2*Math.PI) * Math.asin (c/a);
		}
		if (t < 1) {
			return - 0.5*(a*Math.pow(2,10*(t-=1)) * 
					Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		}
		return a*Math.pow(2,-10*(t-=1)) * 
				Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;
	},
	backIn: function(t, b, c, d, s){
		if (typeof s == 'undefined') {
		   s = 1.70158;
		}
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	backOut: function(t, b, c, d, s){
		if (typeof s == 'undefined') {
			s = 1.70158;  //回缩的距离
		}
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	}, 
	backBoth: function(t, b, c, d, s){
		if (typeof s == 'undefined') {
			s = 1.70158; 
		}
		if ((t /= d/2 ) < 1) {
			return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		}
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	bounceIn: function(t, b, c, d){
		return c - Tween['bounceOut'](d-t, 0, c, d) + b;
	},       
	bounceOut: function(t, b, c, d){
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
		}
		return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
	},      
	bounceBoth: function(t, b, c, d){
		if (t < d/2) {
			return Tween['bounceIn'](t*2, 0, c, d) * 0.5 + b;
		}
		return Tween['bounceOut'](t*2-d, 0, c, d) * 0.5 + c*0.5 + b;
	}
};




function transform(el,attr,val){
  if(typeof el != 'undefined' && typeof attr != 'undefined'){

     if(!el.transform){
      el.transform = {};
     }

     if(typeof val == 'undefined'){
      //获取值
      return el.transform[attr] || null;
     }else{
      //设置值
      el.transform[attr] = val;

      var _setStr = '';

      for(var per in el.transform){

        if(per.indexOf('rotate')!=-1 || per.indexOf('skew')!=-1){
          _setStr+=per+'('+ el.transform[per] +'deg) ';
        }else if(per.indexOf('scale')!=-1){
          _setStr+=per+'('+ el.transform[per] +') ';
        }else if(per.indexOf('translate')!=-1){
          _setStr+=per+'('+ el.transform[per] +'px) ';
        }else{
          _setStr+=per+'('+ el.transform[per] +'px) ';
        }

      }

      el.style.WebkitTransform = el.style.transform = _setStr;

      return _setStr;

     }

  }else{
    return null;
  }
}

function css(el,attr,val){

  if(typeof el != 'undefined' && typeof attr != 'undefined'){


    if(attr.indexOf('rotate')!=-1 || attr.indexOf('skew')!=-1 || attr.indexOf('scale')!=-1 || attr.indexOf('translate')!=-1){
      return transform(el,attr,val);
    }

    //获取值
    if(typeof val == 'undefined'){
      let iVal = parseFloat(getComputedStyle(el)[attr]);
      return isNaN(iVal) ? null : iVal;
    }else{

      //设置值
      if(attr=='opacity'){
        el.style[attr] = val;
      }else{
        el.style[attr] = val + 'px';
      }

    }

  }else{
    return null;
  }

}


function startMove(init){
	var t = 0; //每次循环所执行的次数
	var b = {};//动画执行前的初始值
	var c = {};//动画执行的最终差值
	var d = Math.ceil(init.time / 16.7); //动画执行的总次数

	cancelAnimationFrame(init.el.timer);


	//设置默认值与最终差值
	for(var attr in init.target){
		b[attr] = css(init.el,attr);
		c[attr] = init.target[attr] - b[attr];

	}


	init.el.timer = requestAnimationFrame(move);


	function move(){
		if(t > d || d == 0){
			cancelAnimationFrame(init.el.timer);
			init.callBack && init.callBack.call(init.el);
		}else{


			for(var attr in init.target){
				var val = Tween[init.type](t++,b[attr],c[attr],d);
				css(init.el,attr,val);
			}
			init.callIn && init.callIn.call(init.el);
			init.el.timer = requestAnimationFrame(move);
		}

	}
}



function swiper(init){
	var wrap = init.wrap;//滑屏元素的父级
	var scroll = wrap.children[0];//滑动的元素
	var startPonit = {};//手指的初始位置
	var startEl = {};// 元素的初始位置
	var dir = init.dir;
	var isFirst = true; //判断用户是否 是第一次执行move;
	var lastTime = 0;
	var lastTimeDis = 0;
	var min = {
		x:0,
		y:0
	}
	var isDir = { //判断用户在对哪个方向进行滑屏
		x: false,
		y: false
	};
	var dirTranslate = {
		x: "translateX",
		y: "translateY"
	};
	var lastPoint = {};
	var lastDis = 0;//最后一次的手指移动距离
	css(scroll,"translateX",0);
	css(scroll,"translateY",0);
	css(scroll,"translateZ",0.01);

	wrap.addEventListener('touchstart', function(e) {
		cancelAnimationFrame(scroll.timer);
		init.start&&init.start.call(wrap,e);
		var touch = e.changedTouches[0];
		startPonit = {
			x: touch.pageX,
			y: touch.pageY
		};
		lastPoint = {
			x: touch.pageX,
			y: touch.pageY
		};
		startEl = {
			x: css(scroll,"translateX"),
			y: css(scroll,"translateY")
		};
		min = {
			x: wrap.clientWidth - scroll.offsetWidth,
			y: wrap.clientHeight - scroll.offsetHeight
		}
		lastTime = Date.now();
		lastTimeDis = 0;
		lastDis = 0;
	});
	wrap.addEventListener('touchmove', function(e) {
		var touch = e.changedTouches[0];
		var nowTime = Date.now();
		var nowPonit = {
			x: touch.pageX,
			y: touch.pageY
		};
		if(lastPoint.x == nowPonit.x && lastPoint.y == nowPonit.y){
			return;
		}
		var dis = {
			x: nowPonit.x - startPonit.x,
			y: nowPonit.y - startPonit.y
		};
		if(isFirst){
			if(Math.abs(dis.x) > Math.abs(dis.y)) {
				isDir.x = true;
				isFirst = false;
			} else {
				isDir.y = true;
				isFirst = false;
			}
		 }
		var target = {
			x: startEl.x + dis.x,
			y: startEl.y + dis.y
		};
		if(isDir[dir]){
		 	if(init.backOut == "none"){//不允许用户滑动超出
		 		target[dir] = target[dir] > 0 ? 0 : target[dir];
		 		target[dir] = target[dir] < min[dir] ? min[dir] : target[dir];
		 	} else if(init.backOut == "out"){ //超出添加回弹
		 		if(target[dir] > 0){
		 			var over = target[dir];
		 			var F = getF(over);
		 			over *= F;
		 			target[dir] = over;
		 		} else if(target[dir] < min[dir]){
		 			var over =  min[dir] - target[dir];
		 			var F = getF(over);
		 			over *= F;
		 			target[dir] = min[dir] - over;
		 		}

		 	}
		 	css(scroll,dirTranslate[dir],target[dir]);
			lastDis = nowPonit[dir] - lastPoint[dir];//获取最后一次的距离
			lastTimeDis = nowTime - lastTime;
			e.preventDefault();
		}
		init.move && init.move.call(wrap,e);
		lastPoint.x = nowPonit.x;
		lastPoint.y = nowPonit.y;
		lastTime = nowTime;
	});
	wrap.addEventListener('touchend', function(e) {
		var nowTime = Date.now();//手指抬起时的时间
		if(nowTime - lastTime >= 100){
			// 判断 当用户手指抬起时 和 最后一次移动的时候，有比较大的一个时间间隔，就可以认定 用户在抬起手指前有那么一段时间是按着不动的，那么我们也就不执行缓冲
			lastDis = 0;
		}
		var lastSpeed = lastDis / lastTimeDis;//最后一次移动速度
		lastSpeed = lastSpeed ? lastSpeed : 0;
		/* 最后一次的速度越大，位移出去的距离越大 */
		var s = lastSpeed * 140;//缓冲出去的距离

		var now = css(scroll,dirTranslate[dir]);
		s = Math.round(s + now);
		if(s > 0){
			s = 0;
		} else if(s < min[dir]){
			s = min[dir];
		}
		if(dir == "x"){
			var target = {translateX: s}
		} else {
			var target = {translateY: s}
		}
		if(startEl[dir] != now){
			var time = Math.abs(s - now) * 1.15;
			startMove({
				el: scroll,
				type: "easeOutStrong",
				time: time,
				target: target,
				callIn: function(){
					init.move && init.move.call(wrap,e);
				},
				callBack: function(){
					init.over && init.over.call(wrap,e);
				}
			});
		}
		isFirst = true;
		isDir = {
			x: false,
			y: false
		};
		init.end && init.end.call(wrap,e);
	});
	function getF(over){
		var max = dir == "x" ? wrap.clientWidth : wrap.clientHeight;
		var F = 1 - over / max;
		F = F < .4 ? .4 : F;
		return F;
	}
}


function swiperBar(init){
	var wrap = init.wrap;
	var scroller = wrap.children[0];
	var dir = init.dir;
	var scale = 1;
	var bar = document.createElement('span');
	var commonCss = "position:absolute;background-color:rgba(0,0,0,.5);boder-radius:5px;opacity:0;transition:opacity .8s;";
	if(dir=='x'){
		scale = wrap.clientWidth / scroller.offsetWidth;
		bar.style.cssText = commonCss + 'left:0;bottom:0;height:6px;';
		bar.style.width = wrap.clientWidth * scale + 'px';
	}else if(dir == 'y'){
		scale = wrap.clientHeight / scroller.offsetHeight;
		bar.style.cssText = commonCss + 'right:0;top:0;width:6px;';
		bar.style.height = wrap.clientHeight * scale + 'px';
	}

	var dirTranslate = {
		x:'translateX',
		y:'translateY'
	};

	bar.className = init.className || 'scroll-bar';
	wrap.appendChild(bar);

	swiper({
		wrap:wrap,
		dir:dir,
		backOut:init.backOut,
		start:function(e){
			
			init.start && init.start.call(wrap,e);
		},
		move:function(e){
			if(css(bar,'opacity')==0){
				css(bar,'opacity',1);
			}
			var now = css(scroller,dirTranslate[dir]);
			css(bar,dirTranslate[dir],-now * scale);
			init.move && init.move.call(wrap,e);
		},
		end:function(e){
			init.end && init.end.call(wrap,e);
		},
		over:function(e){
			css(bar,'opacity',0);
			init.over && init.over.call(wrap,e);
		}
	})

}

function gesture(init){
	var isGesTure = false;
	var el = init.el;
	var startDis = 0;
	var startDeg = 0;

	function getDis(point1,point2){
		var x = Math.abs(point2.pageX - point1.pageX);
		var y = Math.abs(point2.pageY - point1.pageY);
		return Math.sqrt(x*x + y*y);
	}
	function getDeg(point1,point2){
		var x = Math.abs(point2.pageX - point1.pageX);
		var y = Math.abs(point2.pageY - point1.pageY);

		return Math.atan2(y,x) * 180 / Math.PI;
	}


	el.addEventListener('touchstart',function(ev){
		var touchs = ev.touches;
		if(touchs.length >=2){
			isGesTure = true;
			startDis = getDis(touchs[0],touchs[1]);
			startDeg = getDeg(touchs[0],touchs[1]);
			init.start && init.start.call(el,ev);
		}else{
			isGesTure = false;
			startDis = 0;
			startDeg = 0;
		}
	});

	el.addEventListener('touchmove',function(ev){
		var touchs = ev.touches;
		if(touchs.length >=2 && isGesTure){
			var nowDis = getDis(touchs[0],touchs[1]);
			var nowDeg = getDeg(touchs[0],touchs[1]);
			ev.scale = nowDis / startDis;
			ev.rotation = nowDeg - startDeg;
			init.change && init.change.call(el,ev);
		}
	});

	el.addEventListener('touchend',function(ev){

		var touchs = ev.touches;
		
		if(touchs.length >=2){
			isGesTure = true;
			startDis = getDis(touchs[0],touchs[1]);
			startDeg = getDeg(touchs[0],touchs[1]);
		}else{
			isGesTure = false;
			startDis = 0;
			startDeg = 0;
		}

		if(!isGesTure){
			init.end && init.end.call(el,ev);
		}
		
	});
}

function drag(init){
	var isDrag = false;
	var el = init.el;
	var startPoint = {
		x:0,
		y:0
	};
	el.addEventListener('touchstart',function(e){
		var touchs = e.touches;
		if(touchs.length == 1){
			isDrag = true;
			startPoint = {
				x:touchs[0].pageX,
				y:touchs[0].pageY
			}
			init.start && init.start.call(el,e);
		}else{
			isDrag = false;
			startPoint = {
				x:0,
				y:0
			};
		}

	});

	el.addEventListener('touchmove',function(e){
		var touchs = e.touches;
		if(touchs.length==1 && isDrag){

			var nowPoint = {
				x:touchs[0].pageX,
				y:touchs[0].pageY
			}

			e.pointDis = {
				x:nowPoint.x - startPoint.x,
				y:nowPoint.y - startPoint.y
			}

			init.move && init.move.call(el,e)

		}
	});


	el.addEventListener('touchend',function(e){


		var touchs = e.touches;
		
		if(touchs.length == 1){
			isDrag = true;
			startPoint = {
				x:touchs[0].pageX,
				y:touchs[0].pageY
			}
		}else{
			isDrag = false;
			startPoint = {
				x:0,
				y:0
			};
		}

		if(!isDrag){
			init.end && init.end.call(el,e);
		}


	})



}
